﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.IO;
using iTextSharp.text;
using iTextSharp.text.pdf;
//using iTextSharp.text.pdf.parser;
using System.Drawing.Imaging;

using ZXing;
using ZXing.Common;
using ZXing.Rendering;
using ZXing.QrCode;
using ZXing.QrCode.Internal;
using System.Drawing.Printing;
using System.Diagnostics;
using Microsoft.Win32;
using System.ComponentModel;
using System.Data;
using System.Drawing;


namespace SocketClient
{
    class PdfHelper
    {
        // 全局变量
        private static string lastFolderPath = ""; // 记录上次选择文件夹的路径
        private static string inputFolderPath = ""; // 输入文件夹路径
        private static string outputFolderPath = ""; // 输出文件夹路径
        // 生成目录相关
        List<string> listFileName = new List<string>(); // 所有文件文件名
        List<int> listFileFirstPageNum = new List<int>(); // 所有文件起始页的页码
        int countPage = 0; // 所有的页面累加

        public void addQRCodeToPdf(string inputPdfPath, string outputPdfPath, string qrText)
        {
            // 创建一个二维码
            var writer = new BarcodeWriter
            {
                Format = BarcodeFormat.QR_CODE,
                Options = new QrCodeEncodingOptions
                {
                    Height = 100,
                    Width = 100
                }
            };
            var qrImage = writer.Write(qrText);

            // 打开现有的PDF文件
            PdfReader pdfReader = new PdfReader(inputPdfPath);
            using (FileStream fs = new FileStream(outputPdfPath, FileMode.Create, FileAccess.Write, FileShare.None))
            {
                using (PdfStamper pdfStamper = new PdfStamper(pdfReader, fs))
                {
                    // 将二维码图片添加到PDF
                    PdfContentByte pdfData = pdfStamper.GetOverContent(1); // 1是第一页
                    iTextSharp.text.Image codeImage = iTextSharp.text.Image.GetInstance(qrImage, System.Drawing.Imaging.ImageFormat.Png);
                    codeImage.SetAbsolutePosition(10, 10); // 设置二维码位置
                    pdfData.AddImage(codeImage);

                    pdfStamper.Close();
                    
                }
            }
            pdfReader.Close();
        }
        //public void rotatePdf(String sourceFile)
        //{
        //    bool rotationFlag = false;
        //    PdfReader pdfReader = new PdfReader(sourceFile);
        //    // 获取第一页的页面字典
        //    PdfDictionary pageDict = pdfReader.GetPageN(1);

        //    // 获取页面旋转角度
        //    int rotation = 0;
        //    if (pageDict.Contains(PdfName.ROTATE))
        //    {
        //        rotation = pageDict.GetAsNumber(PdfName.ROTATE).IntValue;
        //    }
        //    if (rotation == 90 || rotation == 270)
        //    {

        //    }
        //    else
        //    {
        //        rotationFlag = true;
        //    }
        //    pdfReader.Close();
        //    rotate(sourceFile, targetFile, rotationFlag ? -90 : 0);

        //}

        /**
 * 旋转PDF文件
 * @param sourceFile 源PDF文件路径
 * @param targetFile 目标PDF文件路径
 * @param angle 旋转角度
 */
     public  void rotate(String sourceFile, String targetFile) {

         try {
             using (FileStream fs = new FileStream(targetFile, FileMode.Create))
             {
                  int angle;
                    Document document = null;
                    bool rotationFlag = false;
                    PdfReader reader = new PdfReader(sourceFile);
                    // 获取第一页的页面字典
                    PdfDictionary pageDict = reader.GetPageN(1);

                    // 获取页面旋转角度
                    int rotation = 0;
                    if (pageDict.Contains(PdfName.ROTATE))
                    {
                        rotation = pageDict.GetAsNumber(PdfName.ROTATE).IntValue;
                    }
                    if (rotation == 90 || rotation == 270)
                    {

                    }
                    else
                    {
                        rotationFlag = true;
                    }

                    angle = rotationFlag ? -90 : 0;
                    // 读取源文件
                    //reader = new PdfReader(sourceFile);
                    // 创建新的文档
                    document = new Document();
                    // 创建目标PDF文件
                    //outputStream = new FileOutputStream(targetFile);
                    PdfCopy pdfCopy = new PdfSmartCopy(document, fs);

                    // 获取源文件的页数
                    int pages = reader.NumberOfPages;
                    document.Open();
                    PdfDictionary pdfDictionary;

                    // 注意此处的页码是从1开始
                    for (int page = 1; page <= pages; page++) {
                        pdfDictionary = reader.GetPageN(page);
                        if (angle != 0) {
                            pdfDictionary.Put(PdfName.ROTATE, new PdfNumber(angle));
                        }
                        pdfCopy.AddPage(pdfCopy.GetImportedPage(reader, page));
                    }
                    reader.Close();
                    document.Close();
             }
        } catch (Exception e) {
            
        } finally {
           
        }
    }
        public void printPdfViewer(String inputPdfPathFile)
        {
            // 打开默认的打印对话框
            ProcessStartInfo startInfo = new ProcessStartInfo
            {
                FileName = "msedge.exe",
                Arguments = inputPdfPathFile,
                UseShellExecute = true
            };
            Process.Start(startInfo);
        }

        public Dictionary<String, String> pdfFileSearchAndCopy(string sourceDirectory, string destinationDirectory, Dictionary<string, WomWorkOrderItemPage> woMap)
        {
            //string sourceDirectory = @"C:\source_directory"; // 要搜索的目录
            //string destinationDirectory = @"C:\destination_directory"; // 目标目录
            //string searchPattern = "*.pdf"; // 搜索模式

            Dictionary<String, String> map = new Dictionary<String, String>();

            foreach (String key in woMap.Keys)
            {
                WomWorkOrderItemPage item = woMap[key];
              String copyFileName =  CopyPdfFiles(sourceDirectory, destinationDirectory, "*-(" + item.code + ").pdf",item.workOrderNumber);
              map[destinationDirectory + "\\" + copyFileName] = item.workOrderNumber;
            }
            return map;
        }
        public String CopyPdfFiles(string sourceDir, string destDir, string searchPattern,string wonumber)
        {
            // 确保目标目录存在
            Directory.CreateDirectory(destDir);
            String copyFileName = "";
            // 搜索源目录及其所有子目录中的PDF文件
            foreach (string filePath in Directory.GetFiles(sourceDir, searchPattern, SearchOption.AllDirectories))
            {
                string fileName = wonumber + "-"  + Path.GetFileName(filePath);
                string destFilePath = Path.Combine(destDir, fileName);
 
                // 复制文件到目标目录
                File.Copy(filePath, destFilePath, true); // true 表示如果文件存在则覆盖
                copyFileName = fileName;
            }
            return copyFileName;
        }
        public void pdfFileSearch(string startDirectory, string searchPattern)
        {
            //string startDirectory = @"C:\barcode"; // 指定的目录
            //string searchPattern = "*.pdf"; // 模糊查询模式
            RecurseDirectories(startDirectory, searchPattern);
        }
        public void RecurseDirectories(string path, string searchPattern)
        {
            try
            {
                // 获取指定目录中的文件列表
                var files = Directory.EnumerateFiles(path, searchPattern, SearchOption.AllDirectories);

                // 遍历所有PDF文件
                foreach (var file in files)
                {
                    Console.WriteLine(file);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Error: " + e.Message);
            }
        }

        /// <summary>
        /// 合并多个PDF文件为一个PDF文件
        /// </summary>
        /// <param name="inputFolderPath"></param>
        /// <param name="outputFolderPath"></param>
        /// <param name="outputPdfName"></param>
        public void MergePDFs(string inputFolderPath, string outputFolderPath, string outputPdfName)
        {
            // 每次合并前先清空目录信息
            listFileName.Clear();
            listFileFirstPageNum.Clear();
            countPage = 0;
            // 获取输入文件夹中所有的PDF文件  
            //string[] inputFiles = Directory.GetFiles(inputFolderPath, "*.pdf");
            string[] inputFiles = GetAllPdfFiles(inputFolderPath);
            // 创建输出PDF文件路径  
            string outputPdfPath = Path.Combine(outputFolderPath, outputPdfName);
            // 创建输出PDF文件  
            using (FileStream stream = new FileStream(outputPdfPath, FileMode.Create))
            {
                Document pdfDoc = new Document();
                PdfCopy pdf = new PdfCopy(pdfDoc, stream);
                pdfDoc.Open();
                foreach (string file in inputFiles)
                {
                    // 读取每个PDF文件并将其页面添加到输出PDF中  
                    PdfReader reader = new PdfReader(file);
                    int n = reader.NumberOfPages;
                    for (int i = 1; i <= n; i++)
                    {
                        pdf.AddPage(pdf.GetImportedPage(reader, i));
                        countPage++; // 总页面累加
                    }
                    reader.Close();
                    listFileFirstPageNum.Add(countPage); // 添加每个文件起始页的页码
                    string fileName = Path.GetFileName(file);
                    listFileName.Add(fileName.Split('.')[0]); // 添加每个文件的名称
                }
                if (pdfDoc != null)
                {
                    pdfDoc.Close();
                }
                stream.Close();
            }
            string newOutputPdfPath = Path.Combine(outputFolderPath, "AllPDF_Merged.pdf");
            // 检查新输出文件是否已存在  
            if (File.Exists(newOutputPdfPath))
            {
                // 如果已存在，则删除旧文件并创建新文件  
                File.Delete(newOutputPdfPath);
            }
            // 重命名输出PDF文件  
            File.Move(outputPdfPath, newOutputPdfPath);
            // 添加页码  参数是输入文件、输出文件
            PdfAddPageNumber(newOutputPdfPath, Path.Combine(outputFolderPath, "MergedWithPageNumbers.pdf"));
            // 目录需要封面信息和每个文件第一页开始的页码。 文件名、文件名对应的第一个页码、最开始添加页并能放得下页信息
            CreatePdfCatalogue(listFileName, listFileFirstPageNum, outputFolderPath);
        }
        // 递归函数，用于从给定文件夹及其所有子文件夹中获取所有PDF文件  
        private string[] GetAllPdfFiles(string folderPath)
        {
            List<string> pdfFiles = new List<string>();
            // 获取指定文件夹中的所有PDF文件路径，并添加到列表中  
            string[] files = Directory.GetFiles(folderPath, "*.pdf");
            pdfFiles.AddRange(files);
            // 遍历文件夹中的每个子文件夹，并递归调用GetAllPdfFiles函数以获取子文件夹中的PDF文件路径，然后添加到列表中  
            foreach (string subDir in Directory.GetDirectories(folderPath))
            {
                pdfFiles.AddRange(GetAllPdfFiles(subDir));
            }
            // 将PDF文件路径列表转换为数组并返回  
            return pdfFiles.ToArray();
        }
        /// <summary>
        /// 生成目录PDF
        /// </summary>
        /// <param name="fileNames"></param>
        /// <param name="filePageNums"></param>
        /// <param name="outputPath"></param>
        private void CreatePdfCatalogue(List<string> fileNames, List<int> filePageNums, string outputPath)
        {
            // 创建PDF文件
            FileStream pdfFs = new FileStream(Path.Combine(outputPath, "目录.pdf"), FileMode.Create);
            // 获取实例
            Document doc = new Document();
            doc.SetPageSize(PageSize.A4.Rotate()); // 设置页面横向
            doc.SetMargins(50, 50, 30, 30);
            PdfWriter writer = PdfWriter.GetInstance(doc, pdfFs);
            // 打开pdf
            doc.Open();
            // 基本字体信息，可显示中文
            BaseFont bfChinese = BaseFont.CreateFont(@"C:\Windows\Fonts\simkai.ttf", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED); // 设置基础字体
            Paragraph paragCatalog = new Paragraph("目录\n\n", new iTextSharp.text.Font(bfChinese, 30)); // 设置目录段落的内容和字体
            paragCatalog.Alignment = Element.ALIGN_CENTER; // 目录居中对齐
            doc.Add(paragCatalog); // 添加目录名称
            for (int i = 0; i < fileNames.Count; i++)
            {
                string rowInfo = (i + 1).ToString() + " " + fileNames[i] + "............";
                Paragraph paragInfo = new Paragraph(rowInfo, new iTextSharp.text.Font(bfChinese, 14)); // 设置目录条目内容和字体
                paragInfo.Alignment = Element.ALIGN_LEFT;
                doc.Add(paragInfo); // 添加每一条目录信息
                Paragraph paragInfo2 = new Paragraph((i + 1).ToString() + "." + filePageNums[i].ToString(), new iTextSharp.text.Font(bfChinese, 14)); // 设置目录条目内容和字体
                paragInfo2.Alignment = Element.ALIGN_RIGHT;
                doc.Add(paragInfo2); // 添加每一条目录信息
            }
            if (doc != null)
            {
                doc.Close();
            }
            if (pdfFs != null)
            {
                pdfFs.Close();
            }
        }
        /// <summary>
        /// 添加页码
        /// </summary>
        /// <param name="pdfPath">pdf文件</param>
        /// <param name="outPath">输出文件位置</param>
        public static void PdfAddPageNumber(string pdfPath, string outPath)
        {
            //读取pdf
            iTextSharp.text.pdf.PdfReader reader = new iTextSharp.text.pdf.PdfReader(pdfPath);
            //创建新pdf
            System.IO.Stream outStream = new System.IO.FileStream(outPath, System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.None);
            iTextSharp.text.pdf.PdfStamper stamper = new iTextSharp.text.pdf.PdfStamper(reader, outStream); ;
            int pdfTotalPage = reader.NumberOfPages;//总页数
            //第一页pdf尺寸
            iTextSharp.text.Rectangle psize = reader.GetPageSize(1);
            float width = psize.Width;
            float height = psize.Height;
            iTextSharp.text.pdf.PdfContentByte content;
            //【C:\WINDOWS\Fonts】系统字体存放位置
            iTextSharp.text.pdf.BaseFont font = iTextSharp.text.pdf.BaseFont.CreateFont(@"C:\WINDOWS\Fonts\SIMFANG.TTF", iTextSharp.text.pdf.BaseFont.IDENTITY_H, iTextSharp.text.pdf.BaseFont.EMBEDDED);
            iTextSharp.text.pdf.PdfGState gs = new iTextSharp.text.pdf.PdfGState();
            ///添加页码
            for (int i = 1; i <= pdfTotalPage; i++)
            {
                content = stamper.GetOverContent(i);//添加在内容上层，GetUnderContent内容下层
                gs.FillOpacity = 0.8f;//设置透明度
                content.SetGState(gs);
                content.BeginText();
                content.SetColorFill(iTextSharp.text.BaseColor.BLACK);//设置字体颜色
                content.SetFontAndSize(font, 10);//设置字体大小
                content.ShowTextAligned(iTextSharp.text.Element.ALIGN_BASELINE, "第" + i + "页，共" + pdfTotalPage + "页", width / 2 - 15, 12, 0);//设置字体添加位置
                content.EndText();
            }
            stamper.Close();
            reader.Close();
        }
    }
}
